// import { sleep } from './common';
import { IBUS, IbaseModule, IListener, IBusClass } from './type';
class Listener implements IListener {
    EventBus: Array<Function>;
    constructor() {
        this.EventBus = [];
    }
    /**
     *
     * @param data Module_Bus, 输入总线，每次output时主动调用总线的input方法
     */
    addEventListener(data: Function): void {
        this.EventBus.push(data);
    }
    /**
     *
     * @param green 总线数据
     */
    emitListener(green: IBUS) {
        this.EventBus.forEach((ele) => {
            ele(green);
            // ele.input(green)
        });
    }
}
class BaseModule extends Listener {
    protected E: number;
    protected K: number;
    protected EType: number;
    protected green: IBUS;
    protected constructor() {
        super();
        this.E = 0;
        this.K = 0;
        this.EType = 0;
        this.green = { E: this.E };
    }
}
/**
 * E address
 * EType
 *  1: keyboard
 *  2: controller
 */
class Module_Keyboard extends BaseModule implements IbaseModule {
    /*
    n = [0,9]  // number 0-9
    n = 10 // =
    n = [11,14] // + - * /
  */
    constructor(address = 1) {
        super();
        this.E = address;
        this.EType = 1;
        this.K = 1;
    }
    insert(data: number): void {
        // if ()
        // const key:string = 'k'+data;
        console.log(`============== Module_Keyboard insert ${data}`);
        this.K = data;
        this.output();
    }
    input(): void {
        //
    }
    output() {
        this.green = {
            ...this.green,
            E: this.E,
            K: this.K
        };
        this.emitListener(this.green);
    }
}
class Module_Machine implements IBusClass {
    busArray: IBUS;
    address = 0;
    keyboard: Module_Keyboard;
    register: Module_Register;
    controller: Module_Controller;
    num: number;
    constructor(address = 3) {
        this.num = 0;
        this.busArray = { E: address };
        this.register = new Module_Register();
        this.register.addEventListener((data: IBUS) => this.emitFun(data));
        this.controller = new Module_Controller();
        this.controller.addEventListener((data: IBUS) => this.emitFun(data));
        this.keyboard = new Module_Keyboard();
        this.keyboard.addEventListener((data: IBUS) => this.emitFun(data));
    }
    emitFun(data: IBUS) {
        // await sleep(1000);
        console.log('Module_Machine emitFun:', data);
        this.busArray = {
            ...this.busArray,
            ...data
        };
        const busArray = JSON.parse(JSON.stringify(this.busArray));
        // publish
        // setTimeout(() => {
        //     this.controller.input(this.busArray);
        // }, 0);
        // setTimeout(() => {
        //     this.register.input(this.busArray);
        // }, 0);
        console.log('this.num==', this.num);
        console.log(111, busArray);
        this.register.input(busArray);
        console.log(222, busArray);
        this.controller.input(busArray);
        console.log(333, busArray);
        // clear
        this.num++;
        this.busArray = {
            E: this.address
        };
    }
    init(): void {
        console.log('Module_Machine init , insert to keyboard(1) : 1');
        this.keyboard.insert(1);
        console.log('Module_Machine init , insert to keyboard(11) : +');
        this.keyboard.insert(11);
        console.log('Module_Machine init , insert to keyboard(2) : 2');
        this.keyboard.insert(2);
        console.log('Module_Machine init , insert to keyboard(10) : =');
        this.keyboard.insert(10);
    }
}
class Module_Register extends BaseModule implements IbaseModule {
    catch: Array<number>;
    constructor(address = 4, length = 5) {
        super();
        this.E = address;
        this.EType = 4;
        this.catch = [];
        for (let i = 0; i < length; i++) {
            this.catch.push(0);
        }
    }
    input(green: IBUS): void {
        console.log('Module_Register input: ', green);
        const { Black, Gray, M, E } = green;
        if (E === this.E || Black === undefined || M === undefined) return;
        if (Black === 2) {
            this.output(this.catch[M]);
        } else if (Black === 1) {
            if (Gray === undefined) return;
            this.catch[M] = Gray;
        }
    }
    output(K: number) {
        this.green = {
            ...this.green,
            E: this.E,
            K
        };
        this.emitListener(this.green);
    }
}
class Module_Controller extends BaseModule implements IbaseModule {
    catch: Array<number>;
    constructor(address = 2) {
        super();
        this.E = address;
        this.EType = 2;
        this.catch = [0, 0, 0, 0];
    }
    input(green: IBUS): void {
        console.log('Module_Controller input: ', green);
        const { K, E } = green;
        if (E === this.E || typeof K !== 'number') return;
        if (K >= 0 && K <= 9) {
            // num
            if (this.catch[0] === 0) {
                this.catch[1] = this.catch[1] * 10 + K;
            } else {
                this.catch[2] = this.catch[2] * 10 + K;
            }
            console.log(`Module_Controller insert num ${this.catch[0] ? 'second' : 'first'}:`, K);
        }
        if (K === 10) {
            // =
            console.log(`Module_Controller insert equal =:`, K);
            this.catch[3] = this.catch[1] + this.catch[2];
            this.output();
            this.catch[0] = 0;
        }
        if (K > 10 && K <= 14) {
            console.log(`Module_Controller insert sub:`, K);
            // + - * /
            this.catch[0] = K;
        }
    }
    output() {
        this.green = {
            ...this.green,
            C: this.catch[3],
            E: this.E
        };
        this.emitListener(this.green);
    }
}
const res = new Module_Machine();
res.init();
